#ifndef __AEXCEPT_H__
#define __AEXCEPT_H__
#define WIN32_LEAN_AND_MEAN 
#include <Windows.h>

//////////////////////////////////////
typedef enum 
{
	ExceptNone=0, ExceptStream, ExceptSE, ExceptUnknown 
} ExceptTYPE;

LONG WINAPI DbgUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo);
void DisableSetUnhandledExceptionFilter();

////////////////////////////////////////////////////////////////////////////////////
// base class
class CExceptionBase 
{
public:
	CExceptionBase(BOOL bAutoDelete);
	CExceptionBase(LPCTSTR what);
	virtual ~CExceptionBase();
public:
	virtual void GetErrorMessage( LPTSTR lpszError, UINT nMaxError) = 0;
	virtual void Delete();
	virtual int ReportError( UINT nType = MB_OK, UINT nMessageID = 0 );

	int GetExceptionType() { return m_nExceptionType; }
	int GetErrorCode() { return m_nErrorCode; }

protected:
	int m_nExceptionType;	// by type
	int m_nErrorCode;
	BOOL m_bAutoDelete;
	TCHAR m_WrongMsg[MAX_PATH];
};

class CDataStreamExcept : public CExceptionBase
{
public:
	static void ThrowException(int nError, int nParam1 = 0, int nParam2= 0, int nParam3= 0);
public:
	CDataStreamExcept (BOOL bAutoDelete, int nError, int nParam1, int nParam2, int nParam3);
	virtual ~CDataStreamExcept();
	virtual void GetErrorMessage( LPTSTR lpszError, UINT nMaxError);

	int m_nParam1;
	int m_nParam2;
	int m_nParam3;
};

class CSE_Exception: public CExceptionBase
{
public:
	CSE_Exception(BOOL bAutoDelete, unsigned int nSENumber, _EXCEPTION_POINTERS* pExp);
	CSE_Exception(LPCTSTR what) : CExceptionBase(what), m_nSENumber(0) {}
	~CSE_Exception() {};
public:
	unsigned int		m_nSENumber;
	EXCEPTION_RECORD	m_SERecord;
	CONTEXT				m_SEContext;
	static TCHAR m_szExceptionDir[260];
public:
	virtual void GetErrorMessage( LPTSTR lpszError, UINT nMaxError);
	static void  InitSEException(LPCTSTR szExceptionDir);
	static long  _DbgDumpError(struct _EXCEPTION_POINTERS *excpInfo, LPCTSTR szPrex );
	static void  trans_func( unsigned int uSENum, _EXCEPTION_POINTERS* pExp );
	static int   GetSEExceptionMessage(TCHAR * pszBuf, 
									   int nBufSize, 
									   EXCEPTION_RECORD *pRecord, 
									   DWORD dwCode);
};

// the following error code is the same as Win32 API
#define EXCEPT_NO_ENOUGH_MEMORY		14 // not enough memory.
#define EXCEPT_DISK_IS_FULL			39 // disk is full

// the following error code is NOT Win32 API error codes
#define EXCEPT_NO_BUFFER_TO_READ	12000 // not enough contents to read.
#define EXCEPT_NO_BUFFER_TO_WRITE	12001 // not enough room to write.
#endif